/*
 * Copyright© 2003-2019 浙江汇信科技有限公司, All Rights Reserved.
 */
package com.icinfo.cloud.provider.punish.common.datareport.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.icinfo.cloud.common.core.config.RedisRepository;
import com.icinfo.cloud.provider.common.constant.Constant;
import com.icinfo.cloud.provider.common.enums.TerritoryCodeEnum;
import com.icinfo.cloud.provider.common.enums.YesOrNoEnum;
import com.icinfo.cloud.provider.common.exception.BusinessException;
import com.icinfo.cloud.provider.common.utils.*;
import com.icinfo.cloud.provider.punish.common.datareport.dto.CaseDataReportRecordQueryDto;
import com.icinfo.cloud.provider.punish.common.datareport.dto.CaseDataReportRequestCommonDto;
import com.icinfo.cloud.provider.punish.common.datareport.dto.DataReportSpecialStageSpecialCaseDto;
import com.icinfo.cloud.provider.punish.common.datareport.enums.CaseDataReportOptTypeEnum;
import com.icinfo.cloud.provider.punish.common.datareport.enums.ReportDataTypeEnum;
import com.icinfo.cloud.provider.punish.common.datareport.mapper.CaseDataReportRecordMapper;
import com.icinfo.cloud.provider.punish.common.datareport.model.CaseDataReportRecord;
import com.icinfo.cloud.provider.punish.common.datareport.service.ICaseDataReportRecordService;
import com.icinfo.cloud.provider.punish.common.datareport.service.ICaseDataReportSecretReceiveService;
import com.icinfo.cloud.provider.punish.common.datareport.service.ICaseDataReportService;
import com.icinfo.cloud.provider.punish.common.datareport.service.ICaseDataReportStageInfoService;
import com.icinfo.cloud.provider.punish.common.datareport.vo.CaseDataReportRecordVo;
import com.icinfo.cloud.provider.punish.config.mapper.SysDepartParamMapper;
import com.icinfo.cloud.provider.punish.config.model.SysDepartParam;
import com.icinfo.cloud.provider.punish.config.service.ISysDepartParamService;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.CaseTypeEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.CaseMainInfo;
import com.icinfo.cloud.provider.punish.ucase.casemain.service.ICaseMainInfoService;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CaseMainInfoVo;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CasePartiesInfoVo;
import com.icinfo.framework.common.web.Result;
import com.icinfo.framework.core.service.support.MyBatisServiceSupport;
import com.icinfo.framework.mybatis.mapper.entity.Example;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 描述: 案件数据上报记录表 case_data_report_record 对应的Service接口实现类.<br>
 *
 * @author framework generator
 * @date 2022年03月30日
 */
@Service
@Slf4j
public class CaseDataReportRecordServiceImpl extends MyBatisServiceSupport implements ICaseDataReportRecordService {
    @Value("${dataReport.app.key}")
    private String appKey;
    @Value("${dataReport.app.secret}")
    private String requestSecret;
    @Value("${dataReport.reportUrl}")
    private String reportUrl;

    private final SharedHttpUtil httpUtil = SharedHttpUtil.getInstance();
    @Resource
    private CaseDataReportRecordMapper caseDataReportRecordMapper;
    @Resource
    private ICaseDataReportSecretReceiveService caseDataReportSecretReceiveService;
    @Resource
    private ICaseMainInfoService caseMainInfoService;
    @Resource
    private SysDepartParamMapper sysDepartParamMapper;

    @Resource
    private CaseDataReportBasicServiceImpl basicService;
    @Resource
    private CaseDataReportInvestigateServiceImpl investigateService;
    @Resource
    private CaseDataReportObtainServiceImpl obtainService;
    @Resource
    private CaseDataReportInformServiceImpl informService;
    @Resource
    private CaseDataReportHearingServiceImpl hearingService;
    @Resource
    private CaseDataReportDecisionServiceImpl decisionService;
    @Resource
    private CaseDataReportExecuteServiceImpl executeService;
    @Resource
    private CaseDataReportCloseServiceImpl closeService;
    @Resource
    private RedisRepository redisRepository;
    @Resource
    private ISysDepartParamService sysDepartParamService;
    /**
     * 行政基础信息推送接口
     */
    private static final String BASE_HTTP = "E5BeGhl3e4jPUbd8.htm";
    /**
     * 行政处罚调查推送接口
     */
    private static final String INVESTIGATE_HTTP = "GZe1Lafcq66OX67d.htm";
    /**
     * 行政处罚事项告知推送接口
     */
    private static final String INFORM_HTTP = "Af5fA3wf55nzOf2e.htm";

    /**
     * 行政处罚听证推送接口
     */
    private static final String HEAR_HTTP = "1aobklQb64F40R7b.htm";
    /**
     * 行政处罚决定推送接口
     */
    private static final String DECISION_HTTP = "2Yt9eL497ZdbM0bf.htm";
    /**
     * 行政处罚执行推送接口
     */
    private static final String EXECUTE_HTTP = "ydz5c15I5aVW4ru2.htm";
    /**
     * 行政处罚结案推送接口
     */
    private static final String CASE_CLOSED_HTTP = "U0odx61fHvb6Jc1f.htm";

    /**
     * 行政处罚证据推送接口
     */
    private static final String OBTAIN_HTTP = "3L7U056ul98eN9f2.htm";

    @Resource
    private ICaseDataReportStageInfoService caseDataReportStageInfoService;

    /**
     * 描述：获取案件上报记录
     *
     * @param queryDto {@link CaseDataReportRecordQueryDto}
     * @return {@link List < CaseDataReportRecordVo >} 案件上报记录
     * @author xiangyuyu
     * @date 2022-03-30 20:29
     */
    @Override
    public List<CaseDataReportRecordVo> getCaseDataReportRecord(CaseDataReportRecordQueryDto queryDto) {
        List<CaseDataReportRecordVo> list = caseDataReportRecordMapper.selectCaseDataReportRecord(queryDto);
        return list;
    }

    /**
     * 描述：是否上报案件基础信息
     *
     * @param caseId 案件id
     * @return 是否上报（true-是/false-否）
     * @author xiangyuyu
     * @date 2022-04-14 14:50
     */
    @Override
    public boolean isReportCaseBaseInfo(String caseId) {
        boolean flag = true;
        String reportDataType = ReportDataTypeEnum.BASE.getCode();
        CaseDataReportRecordQueryDto queryDto = new CaseDataReportRecordQueryDto();
        queryDto.setReportDataType(reportDataType);
        queryDto.setCaseId(caseId);
        queryDto.setReportFailReason("该条数据已经存在");
        List<CaseDataReportRecordVo> list = getCaseDataReportRecord(queryDto);
        if (ObjectUtils.isEmpty(list) || list.size() == 0) {
            //未上报
            flag = false;
        }
        return flag;
    }

    /**
     * 描述：案件是否上报
     * @param  caseId 案件id
     * @return 是否上报（true-是/false-否）
     * @author lilihao
     * @date 2023/2/6 20:19
     */
    @Override
    public boolean isReportCase(String caseId) {
        boolean flag = true;
        Example example = new Example(CaseDataReportRecord.class);
        example.createCriteria().andEqualTo("caseId",caseId);
        List<CaseDataReportRecord> list = caseDataReportRecordMapper.selectByExample(example);
        if (ObjectUtils.isEmpty(list) || list.size() == 0) {
            //未上报
            flag = false;
        }
        return flag;
    }

    /**
     * 描述：分析上报结果判断是否上报成功
     *
     * @param result {@link Result <String>}
     * @return boolean 是否上报成功(true-是/false-否)
     * @author xiangyuyu
     * @date 2022-04-20 10:51
     */
    @Override
    public boolean analyseResultToJudgeIsReportSuccess(Result<String> result) {
        //判断响应Code
        Integer code = result.getCode();
        if (Constant.INTEGER_200.equals(code)) {
            return true;
        } else {
            //判断msg是否包含"该条数据已存在"，存在这代表已经上报成功（旧数据）
            String msg = result.getMessage();
            if (!ObjectUtils.isEmpty(msg) && msg.contains(Constant.STRING_RECORD_EXISTS)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 描述：数据上报
     *
     * @param uri            接口uri
     * @param reportDataType 上报数据类型
     * @param params         上报数据
     * @param caseMainInfo   案件信息
     * @return String 上报结果错误信息（空代表上报成功）
     * @author xiangyuyu
     * @date 2022-03-30 21:23
     */
    @Override
    public String dataReport(String uri, String reportDataType, Map<String, String> params, CaseMainInfoVo caseMainInfo) {
        log.info("caseMainInfo:{}", caseMainInfo);
        LocalDateTime startTime = LocalDateTime.now();
        CaseDataReportRecord record = new CaseDataReportRecord();
        log.info("dataReport start...startTime:{}", startTime);
        String url = reportUrl + uri;
        String caseId = caseMainInfo.getId();
        String reportActionType = params.get("reportActionType");
        String inputActionType = params.get("inputActionType");
        //清空冗余入参
        params.remove("reportActionType");
        params.remove("envFlag");
        long time = System.currentTimeMillis();
        String secret = caseDataReportSecretReceiveService.getSecret();
        log.info("dataReport secret:{}", secret);
        if (ObjectUtils.isEmpty(secret)) {
            throw new BusinessException("dataReport secret:null");
        }
        String sign = SharedMd5Util.hash(appKey + secret + time);
        params.put("appKey", appKey);
        params.put("sign", sign);
        params.put("requestTime", time + "");
        /*
        数据上报规则：
        0 正式数据
        1 测试数据
         */
        record.setIsTestData(YesOrNoEnum.YES.getCode());
        if (SpringContextUtil.checkIsPrdProfile()) {
            record.setIsTestData(YesOrNoEnum.NO.getCode());
        }
        log.info("dataReport before request...param:", params);
        String result = httpUtil.sendHttpPost(url, params);
        log.info("dataReport after request result:{}", result);
        JSONObject object = JSONObject.parseObject(result);
        String errorMsg = "";
        String reportResult = Constant.STRING_0;
        JSONObject data;
        if (!ObjectUtils.isEmpty(object)) {
            String code = object.getString(Constant.STRING_CODE_LOWER);
            if (Constant.STRING_00.equals(code)) {
                //外层接口ok
                data = object.getJSONObject(Constant.STRING_DATAS_LOWER);
                if (!ObjectUtils.isEmpty(data)) {
                    String innerCode = data.getString(Constant.STRING_CODE_LOWER);
                    if (!Constant.STRING_200.equals(innerCode)) {
                        //内层接口报错
                        reportResult = Constant.STRING_1;
                        errorMsg = "数据上报-inner：" + data.getString(Constant.STRING_CODE_LOWER) + " " + data.getString(Constant.STRING_MSG_LOWER);
                    }
                }
            } else {
                //外层接口报错
                reportResult = Constant.STRING_1;
                errorMsg = "数据上报-outer：" + object.getString(Constant.STRING_CODE_LOWER) + " " + object.getString(Constant.STRING_MSG_LOWER);
            }
        }
        //保存上报记录
        String caseStageCode = caseMainInfo.getCaseCurrentStageCode();
        String caseLinkCode = caseMainInfo.getCaseCurrentLinkCode();


        record.setId(BaseUtil.createUid());
        record.setCaseId(caseId);
        record.setCaseStageCode(ObjectUtils.isEmpty(caseStageCode)?Constant.STRING_HORIZONTAL_BARS:caseStageCode);
        record.setCaseLinkCode(ObjectUtils.isEmpty(caseLinkCode)?Constant.STRING_HORIZONTAL_BARS:caseLinkCode);
        record.setReportDataType(reportDataType);
        record.setReportActionType(ObjectUtils.isEmpty(inputActionType)?reportActionType:inputActionType);
        JSONObject reportDataContent = new JSONObject();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            reportDataContent.put(entry.getKey(), entry.getValue());
        }
        record.setReportDataContent(reportDataContent.toJSONString());
        record.setReportResult(reportResult);
        record.setReportFailReason(errorMsg);

        CaseDataReportRecordQueryDto queryDto = new CaseDataReportRecordQueryDto();
        queryDto.setCaseId(caseId);
        queryDto.setReportDataType(reportDataType);
        queryDto.setIsTestData(YesOrNoEnum.YES.getCode());
        if (SpringContextUtil.checkIsPrdProfile()) {
            queryDto.setIsTestData(YesOrNoEnum.NO.getCode());
        }
        List<CaseDataReportRecordVo> list = getCaseDataReportRecord(queryDto);
        int failCount = 0;
        if (ObjectUtils.isEmpty(errorMsg)) {
            //本次上报成功
            if (!ObjectUtils.isEmpty(list) && list.size() > 0) {
                CaseDataReportRecordVo latestRecord = list.get(Constant.INTEGER_0);
                //取上一次记录下的失败次数
                failCount = latestRecord.getReportFailCount();
            }
            // 第一次就成功，记录0
        } else {
            if (ObjectUtils.isEmpty(list) || list.size() == 0) {
                failCount++;
            } else {
                CaseDataReportRecordVo latestRecord = list.get(Constant.INTEGER_0);
                String latestReportResult = latestRecord.getReportResult();
                if (Constant.STRING_0.equals(latestReportResult)) {
                    //成功
                    failCount++;
                } else {
                    //失败
                    failCount = latestRecord.getReportFailCount() + 1;
                }
            }
        }
        record.setReportFailCount(Integer.valueOf(failCount));
        caseDataReportRecordMapper.insertSelective(record);
        LocalDateTime endTime = LocalDateTime.now();
        log.info("dataReport end ! endTime:{}", endTime);
        if (!ObjectUtils.isEmpty(errorMsg)) {
            errorMsg += "-caseId:" + caseId;
        }
        return errorMsg;
    }


    /**
     * 描述：获取是否允许数据上报
     *
     * @param caseId 案件id
     * @return boolean true-是/false-否
     * @author xiangyuyu
     * @date 2022-04-02 17:09
     */
    @Override
    public boolean getIsAllowDataReport(String caseId) {
        boolean flag = false;
        //获取案件所属部门orgCode
        CaseMainInfoVo caseMainInfoVo;
        try {
            caseMainInfoVo = caseMainInfoService.getCaseMainInfo(caseId);
            if (!ObjectUtils.isEmpty(caseMainInfoVo)) {
                String orgCode = caseMainInfoVo.getCaseOrgCode();
                if (!ObjectUtils.isEmpty(orgCode)) {
                    //查询部门配置信息
                    /*Example e = new Example(SysDepartParam.class);
                    e.createCriteria().andEqualTo("orgCode", orgCode);
                    List<SysDepartParam> sysDepartParamList = sysDepartParamMapper.selectByExample(e);
                    if (!ObjectUtils.isEmpty(sysDepartParamList) && sysDepartParamList.size() > 0) {
                        SysDepartParam sysDepartParam = sysDepartParamList.get(Constant.INTEGER_0);
                        String isAllowDataReportStr = sysDepartParam.getIsAllowDataReport();
                        if (YesOrNoEnum.YES.getCode().equals(isAllowDataReportStr)) {
                            flag = true;
                        }
                    }*/
                    SysDepartParam sysDepartParam =sysDepartParamService.getSysDepartParamByOrgCodeAndDeptCode(orgCode,"");
                    String isAllowDataReportStr = sysDepartParam.getIsAllowDataReport();
                    if (YesOrNoEnum.YES.getCode().equals(isAllowDataReportStr)) {
                        flag = true;
                    }
                }
            } else {
                flag = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 描述： 根据案件id和上报类型获取最新的上报成功记录
     *
     * @author: zhengqiang
     * @date: 2022/7/20
     * @param: caseId
     * @param: reportDataType
     * @return {@link CaseDataReportRecord}
     **/
    @Override
    public CaseDataReportRecord getLatestReportRecord(String caseId, String reportDataType){
        Example report = new Example(CaseDataReportRecord.class);
        report.createCriteria().andEqualTo("caseId", caseId)
                .andEqualTo("reportDataType", reportDataType)
                .andEqualTo("reportResult", Constant.STRING_0);
        report.orderBy("createTime").desc();

        List<CaseDataReportRecord> caseDataReportRecords = caseDataReportRecordMapper.selectByExample(report);
        if (!ObjectUtils.isEmpty(caseDataReportRecords)) {
            return caseDataReportRecords.get(0);
        }
        return null;
    }

    /**
     * 描述： 更新历史行政处罚决定上报成功记录的公示时间及地址
     *
     * @author: zhengqiang
     * @date: 2022/7/26
     * @param: record
     * @return {@link int}
     **/
    @Override
    public int updateHistoryDecisionReport(CaseDataReportRecord record) {
        String reportDataContent = record.getReportDataContent();
        JSONObject reportJson = JSONObject.parseObject(reportDataContent);
        JSONObject decisionObj = reportJson.getJSONObject("decisionInfo");
        JSONObject decisionInfo = decisionObj.getJSONObject("decisionInfo");

        //获取公示时间
        String publicDateStr = decisionInfo.getString("publicDate");
        System.out.println(publicDateStr);
        LocalDateTime publicDate = LocalDateTime.parse(publicDateStr);
        record.setPublicDate(publicDate);
        //拼接url
        String punishDocumentCode = decisionInfo.getString("punishDocumentCode");
        String punishBaseInfoCode = decisionInfo.getString("punishBaseInfoCode");
        try {
            StringBuilder publicUrl = new StringBuilder("https://www.zjzwfw.gov.cn/zjservice/matter/punishment/detail.do?");
            publicUrl.append("unid=").append(URLEncoder.encode(punishDocumentCode, "UTF-8"));
            publicUrl.append("&webid=1");
            publicUrl.append("&guid=").append(punishBaseInfoCode);
            record.setPublicUrl(publicUrl.toString());
        } catch (Exception e) {
            log.error("公示地址拼接异常", e);
        }
        return caseDataReportRecordMapper.updateByPrimaryKeySelective(record);
    }


    /**
     * 描述：个性化校验案件是否允许数据上报（优先取caseMainInfo的内容）
     *
     * @param caseId       案件id
     * @param caseMainInfo {@link CaseMainInfoVo}
     * @return 是否允许数据上报（true-是/false-否）
     * @author xiangyuyu
     * @date 2022/9/16
     * @since 1.4.1
     */
    @Override
    public boolean personalCheckIsAllowDataReport(String caseId, CaseMainInfoVo caseMainInfo) {
        if (ObjectUtils.isEmpty(caseMainInfo)) {
            caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
        }
        if(CaseTypeEnum.SIMPLE_QUICK.getCode().equals(caseMainInfo.getCaseType())){
            log.info("速结程序不上报-caseId:{}", caseId);
            return false;
        }
        caseId = caseMainInfo.getId();
        if (CaseTypeEnum.SIMPLE_PROCEDURE.getCode().equals(caseMainInfo.getCaseType())) {
            //个性化设定 2022-09-16 19:30 台州简易处罚暂不安排数据上报(orgCode以3310开头)
            String orgCode = caseMainInfo.getCaseOrgCode();
            if (!ObjectUtils.isEmpty(orgCode)) {
                /*if (orgCode.startsWith("3310")) {
                    log.info("该案件暂不开启数据上报-caseId:{}", caseId);
                    return false;
                }*/
            } else {
                log.info("该案件暂不开启数据上报(机构编码信息丢失)-caseId:{}", caseId);
                return false;
            }
        }
        return true;
    }

    /**
     * 描述：【V1.4.2】描述：指定阶段指定案件重新数据上报
     *
     * @param dto {@link DataReportSpecialStageSpecialCaseDto}
     * @return Result<String> 上报结果信息
     * @author xiangyuyu
     * @date 2022/9/23
     * @since 1.4.2
     */
    @Override
    public Result<String> dataReportSpecialStageSpecialCase(DataReportSpecialStageSpecialCaseDto dto) {
        String optType = dto.getOptType();
        if(ObjectUtils.isEmpty(optType)){
            optType = CaseDataReportOptTypeEnum.U.getCode();
        }
        if(!CaseDataReportOptTypeEnum.isLegalEnumCode(optType)){
            throw new BusinessException("请指定有效的数据上报更新类型枚举(I：新增， U：修改； D：删除)");
        }
        List<String> caseIdList = dto.getCaseIdList();
        String stageIds = dto.getStageIds();
        String errorMsg = "";
        if (!ObjectUtils.isEmpty(caseIdList) && caseIdList.size() > 0) {
            if (!ObjectUtils.isEmpty(stageIds)) {
                CaseDataReportRequestCommonDto commonDto = new CaseDataReportRequestCommonDto();
                for (String e : caseIdList) {
                    commonDto.setCaseId(e);
                    commonDto.setOptType(optType);
                    if (stageIds.contains(ReportDataTypeEnum.BASE.getCode())) {
                        Result<String> result = basicService.singleCaseReport(commonDto, null, null);
                        errorMsg += result.getMessage();
                    }
                    if (stageIds.contains(ReportDataTypeEnum.INVESTIGATE.getCode())) {
                        Result<String> result = investigateService.singleCaseReport(commonDto, null, null);
                        errorMsg += result.getMessage();
                    }
                    if (stageIds.contains(ReportDataTypeEnum.INFORM.getCode())) {
                        Result<String> result = informService.singleCaseReport(commonDto, null, null);
                        errorMsg += result.getMessage();
                    }
                    if (stageIds.contains(ReportDataTypeEnum.HEAR.getCode())) {
                        Result<String> result = hearingService.singleCaseReport(commonDto, null, null);
                        errorMsg += result.getMessage();
                    }
                    if (stageIds.contains(ReportDataTypeEnum.DECISION.getCode())) {
                        Result<String> result = decisionService.singleCaseReport(commonDto, null, null);
                        errorMsg += result.getMessage();
                    }
                    if (stageIds.contains(ReportDataTypeEnum.EXECUTE.getCode())) {
                        Result<String> result = executeService.singleCaseReport(commonDto, null, null);
                        errorMsg += result.getMessage();
                    }
                    if (stageIds.contains(ReportDataTypeEnum.CASE_CLOSED.getCode())) {
                        Result<String> result = closeService.singleCaseReport(commonDto, null, null);
                        errorMsg += result.getMessage();
                    }
                }
            } else {
                return Result.error("未指定阶段id列表");
            }
        } else {
            return Result.error("未指定案件id列表");
        }
        return Result.success(errorMsg);
    }

    /**
     *  案件更新，重新上报数据
     * @param stageIds
     * @param caseId
     * @param optType
     * @return
     */
    @Override
    public boolean dataReportSpecialStage(String stageIds, String caseId, String optType) {
        if(!CaseDataReportOptTypeEnum.isLegalEnumCode(optType)){
            throw new BusinessException("请指定有效的数据上报更新类型枚举(I：新增， U：修改； D：删除)");
        }
        CaseMainInfoVo caseMainInfo=caseMainInfoService.getCaseMainInfo(caseId);
        CaseDataReportRequestCommonDto commonDto = new CaseDataReportRequestCommonDto();
        commonDto.setCaseId(caseId);
        commonDto.setOptType(optType);
        boolean baseResult = true;
        if (stageIds.contains(ReportDataTypeEnum.BASE.getCode())) {
            if(!TerritoryCodeEnum.RLSB.getCode().equals(caseMainInfo.getCaseTerritoryCode())) {
                Result<String> result = basicService.singleCaseReport(commonDto, null, null);
                if (result.getCode() != Constant.INTEGER_200) {
                    baseResult = false;
                }
            }
        }
        boolean investigateResult = true;
        if (stageIds.contains(ReportDataTypeEnum.INVESTIGATE.getCode())) {
            Result<String> result = investigateService.singleCaseReport(commonDto, null, null);
            if(result.getCode() != Constant.INTEGER_200){
                investigateResult = false;
            }
        }
        boolean informResult = true;
        if (stageIds.contains(ReportDataTypeEnum.INFORM.getCode())) {
            Result<String> result = informService.singleCaseReport(commonDto, null, null);
            if(result.getCode() != Constant.INTEGER_200){
                informResult = false;
            }
        }
        boolean hearingResult = true;
        if (stageIds.contains(ReportDataTypeEnum.HEAR.getCode())) {
            Result<String> result = hearingService.singleCaseReport(commonDto, null, null);
            if(result.getCode() != Constant.INTEGER_200){
                hearingResult = false;
            }
        }
        boolean decisionResult = true;
        if (stageIds.contains(ReportDataTypeEnum.DECISION.getCode())) {
            Result<String> result = decisionService.singleCaseReport(commonDto, null, null);
            if(result.getCode() != Constant.INTEGER_200){
                decisionResult = false;
            }
        }
        boolean executeResult = true;
        if (stageIds.contains(ReportDataTypeEnum.EXECUTE.getCode())) {
            Result<String> result = executeService.singleCaseReport(commonDto, null, null);
            if(result.getCode() != Constant.INTEGER_200){
                executeResult = false;
            }
        }
        boolean closeResult = true;
        if (stageIds.contains(ReportDataTypeEnum.CASE_CLOSED.getCode())) {
            Result<String> result = closeService.singleCaseReport(commonDto, null, null);
            if(result.getCode() != Constant.INTEGER_200){
                closeResult = false;
            }
        }
        return baseResult && investigateResult && informResult && hearingResult && decisionResult && executeResult && closeResult;
    }

    /**
     * 描述：失败重试上报
     *
     * @param dto            {@link CaseDataReportRequestCommonDto}
     * @param partyInfo      {@link CasePartiesInfoVo} 当事人信息
     * @param caseMainInfo   {@link CaseMainInfoVo} 案件主体信息
     * @param service        {@link ICaseDataReportService} 案件主体信息
     * @param reportDataType 数据上报阶段类型
     * @return {@link Result <String>} 上报结果
     * @author xiangyuyu
     * @date 2022/11/29
     * @since
     */
    @Override
    public Result<String> reportAgain(CaseDataReportRequestCommonDto dto, CasePartiesInfoVo partyInfo, CaseMainInfoVo caseMainInfo, ICaseDataReportService service, String reportDataType) {
        log.info("reportAgain start... dto:{}", dto);
        String caseId = dto.getCaseId();
        //重置请求密钥
        redisRepository.del("punish-requestSecretEndTime");
        //今日案件重试次数1次
        LocalDateTime today = LocalDateTime.now();
        Date date = Date.from(today.atZone(ZoneId.systemDefault()).toInstant());
        String dateStr = (new SimpleDateFormat("yyyy-MM-dd")).format(date);
        String caseReportAgainCountKey = caseId + reportDataType + Constant.STRING_UNDERLINE + dateStr;
        String redisCount = redisRepository.get(caseReportAgainCountKey);
        if (!Constant.STRING_1.equals(redisCount)) {
            //记录重试次数
            redisRepository.set(caseReportAgainCountKey, Constant.STRING_1);
            //重试一次
            log.info(caseReportAgainCountKey + "reportAgain operate success");
            return service.singleCaseReport(dto, partyInfo, caseMainInfo);
        }
        log.info(caseReportAgainCountKey + "reportAgain out limit");
        return Result.error(caseReportAgainCountKey + "reportAgain out limit");
    }

    /**
     * 描述：根据历史上报记录参数重新上报
     *
     * @param dto {@link DataReportSpecialStageSpecialCaseDto}
     * @return Result<String> 上报结果信息
     * @author xiangyuyu
     * @date 2023/3/27
     */
    @Override
    public Result<String> dataReportByHistoryReportParam(DataReportSpecialStageSpecialCaseDto dto) {
        log.info("dataReportByHistoryReportParam start... dto:{}", dto);
        String optType = dto.getOptType();
        if (!CaseDataReportOptTypeEnum.isLegalEnumCode(optType)) {
            throw new BusinessException("请指定有效的数据上报更新类型枚举(I：新增， U：修改； D：删除)");
        }
        List<String> caseIdList = dto.getCaseIdList();
        if (ObjectUtils.isEmpty(caseIdList) || caseIdList.size() == 0) {
            throw new BusinessException("请指定案件编号信息");
        }
        String stageIds = dto.getStageIds();
        if (ObjectUtils.isEmpty(stageIds)) {
            throw new BusinessException("请指定案件上报阶段");
        }
        if (stageIds.contains(Constant.STRING_COMMA)) {
            throw new BusinessException("目前上报阶段只适配单阶段");
        }
        //根据案件id+案件阶段获取对应阶段历史上报参数（取最新一条）
        List<CaseDataReportRecord> list = getReportRecordByCaseStageInfo(caseIdList, stageIds);
        if (ObjectUtils.isEmpty(list) || list.size() == 0) {
            throw new BusinessException("存在未匹配到案件上报阶段相关信息");
        }
        try {
            list.forEach(e -> {
                String uri;
                String str;
                JSONObject jsonObject = JSONObject.parseObject(e.getReportDataContent());
                ICaseDataReportService caseDataReportService;
                if (stageIds.equals(ReportDataTypeEnum.BASE.getCode())) {
                    uri = BASE_HTTP;
                    str = jsonObject.getString("baseInfo");
                    caseDataReportService = new CaseDataReportBasicServiceImpl();
                    JSONObject baseInfoJson = JSONObject.parseObject(str);
                    Object updateJson = JsonUtil.updateJson(baseInfoJson, "optType", optType);
                    jsonObject.put("baseInfo", JSONObject.toJSONString(updateJson));
                } else if (stageIds.equals(ReportDataTypeEnum.DECISION.getCode())) {
                    uri = DECISION_HTTP;
                    caseDataReportService = new CaseDataReportDecisionServiceImpl();
                    JSONObject decisionInfoOut = jsonObject.getJSONObject("decisionInfo");
                    JSONObject decisionInfoIn = decisionInfoOut.getJSONObject("decisionInfo");
                    decisionInfoIn.put("isPublic", Constant.STRING_1);
                    decisionInfoIn.put("publicStatus", Constant.STRING_1);
                    decisionInfoIn.put("punishDecisionStatus", Constant.STRING_1);
                    decisionInfoIn.put("punishDecisionCancelDocUrl", decisionInfoIn.get("punishDocument"));
                    decisionInfoIn.put("cutReason", Constant.STRING_HORIZONTAL_BARS);
                    decisionInfoOut.put("decisionInfo",decisionInfoIn);
                    //处罚决定只处理撤案情况，其他情况走指定阶段数据上报即可
                    Object updateJson = JsonUtil.updateJson(decisionInfoOut, "optType", "U");
                    jsonObject.put("decisionInfo", JSONObject.toJSONString(updateJson));
                } else {
                    throw new BusinessException("目前仅支持立案、决定信息的重新上报");
                }
                Map<String, String> params = JSON.parseObject(jsonObject.toString(), Map.class);
                params.put("inputActionType", optType);
                CaseMainInfoVo caseMainInfo = new CaseMainInfoVo();
                String caseId = e.getCaseId();
                String partyId = e.getPartyId();
                caseMainInfo.setId(caseId);

                String errorMsg = dataReport(uri, stageIds, params, caseMainInfo);
                log.info("dataReportByHistoryReportParam end");
                if (ObjectUtils.isEmpty(errorMsg)) {
                    caseDataReportStageInfoService.dealAfterReport(caseId, true, stageIds, null, partyId);
                } else {
                    if (errorMsg.contains(Constant.STRING_RECORD_EXISTS)) {
                        caseDataReportStageInfoService.dealAfterReport(caseId, true, stageIds, errorMsg, partyId);
                    } else if (errorMsg.contains(Constant.STRING_ERROR_SIGN)) {
                        CasePartiesInfoVo partyInfo = new CasePartiesInfoVo();
                        CaseDataReportRequestCommonDto caseDataReportRequestCommonDto = new CaseDataReportRequestCommonDto(caseId, optType);
                        reportAgain(caseDataReportRequestCommonDto, partyInfo, caseMainInfo, caseDataReportService, stageIds);
                    } else {
                        caseDataReportStageInfoService.dealAfterReport(caseId, false, stageIds, errorMsg, partyId);
                    }
                }
            });
        } catch (Exception exe) {
            exe.printStackTrace();
            return Result.error("dataReportByHistoryReportParam catch exception：" + exe.getMessage());
        }
        return Result.success(Constant.STRING_OPERATE_SUCCESS);
    }

    /**
     * 描述：根据案件id+阶段编号[支持集合]查询案件阶段对应最新一条上报记录相关信息
     *
     * @param caseIdList     案件id列表
     * @param reportDataType 数据上报阶段类型
     * @return List<CaseDataReportRecord> 上报记录相关信息列表
     * @author xiangyuyu
     * @date 2023/3/27
     */
    @Override
    public List<CaseDataReportRecord> getReportRecordByCaseStageInfo(List<String> caseIdList, String reportDataType) {
        List<CaseDataReportRecord> list = caseDataReportRecordMapper.selectReportRecordByCaseStageInfo(caseIdList, reportDataType);
        return list;
    }
}